package org.dromara.system.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.constants.OrderConstants;
import org.dromara.system.domain.vo.SysDictDataVo;
import org.dromara.system.service.ISysDictTypeService;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.PayPolicyBo;
import org.dromara.system.domain.vo.PayPolicyVo;
import org.dromara.system.domain.PayPolicy;
import org.dromara.system.mapper.PayPolicyMapper;
import org.dromara.system.service.IPayPolicyService;

import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 风控策略Service业务层处理
 *
 * @author Gavino
 * @date 2024-12-24
 */
@RequiredArgsConstructor
@Service
public class PayPolicyServiceImpl implements IPayPolicyService {

    private final PayPolicyMapper baseMapper;
    private final ISysDictTypeService dictTypeService;

    /**
     * 查询风控策略
     *
     * @param policyId 主键
     * @return 风控策略
     */
    @Override
    public PayPolicyVo queryById(Long policyId){
        PayPolicyVo obj = RedisUtils.getCacheObject(OrderConstants.policy_config + policyId);
        if(obj == null) {
            obj = baseMapper.selectVoById(policyId);
            if(obj != null) {
                RedisUtils.setCacheObject(OrderConstants.policy_config + policyId, obj);
            }
        }
        return obj;
    }

    /**
     * 分页查询风控策略列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 风控策略分页列表
     */
    @Override
    public TableDataInfo<PayPolicyVo> queryPageList(PayPolicyBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PayPolicy> lqw = buildQueryWrapper(bo);
        Page<PayPolicyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的风控策略列表
     *
     * @param bo 查询条件
     * @return 风控策略列表
     */
    @Override
    public List<PayPolicyVo> queryList(PayPolicyBo bo) {
        LambdaQueryWrapper<PayPolicy> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PayPolicy> buildQueryWrapper(PayPolicyBo bo) {
        if(LoginHelper.isManager()) {
            bo.setAgentId(LoginHelper.getLoginUser().getAgentId());
        }
        else if(!LoginHelper.isSuperAdmin()) {
            bo.setAgentId(LoginHelper.getUserId());
        }

        LambdaQueryWrapper<PayPolicy> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getName()), PayPolicy::getName, bo.getName());
        lqw.eq(bo.getType() != null, PayPolicy::getType, bo.getType());
        lqw.eq(bo.getAgentId() != null, PayPolicy::getAgentId, bo.getAgentId());
        return lqw;
    }

    /**
     * 新增风控策略
     *
     * @param bo 风控策略
     * @return 是否新增成功
     */
    @Override
    public R<Void> insertByBo(PayPolicyBo bo) {
        if (!LoginHelper.isSuperAdmin() && !LoginHelper.isAgent()) {
            return R.fail("未授权");
        }

        PayPolicy add = MapstructUtils.convert(bo, PayPolicy.class);
        validEntityBeforeSave(add);

        add.setCreateId(LoginHelper.getUserId());
        add.setCreateName(LoginHelper.getUsername());
        add.setAgentId(add.getCreateId());
        add.setAgentName(add.getCreateName());
        add.setCreateTime(DateUtils.getNowDate());
        add.setUpdateTime(DateUtils.getNowDate());

        setValidName(add);

        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setPolicyId(add.getPolicyId());
        }
        return R.ok();
    }

    /**
     * 修改风控策略
     *
     * @param bo 风控策略
     * @return 是否修改成功
     */
    @Override
    public R<Void> updateByBo(PayPolicyBo bo) {
        if (!LoginHelper.isSuperAdmin() && !LoginHelper.isAgent()) {
            return R.fail("未授权");
        }

        PayPolicy update = MapstructUtils.convert(bo, PayPolicy.class);
        validEntityBeforeSave(update);

        update.setUpdateTime(DateUtils.getNowDate());

        setValidName(update);

        baseMapper.updateById(update);
        RedisUtils.deleteObject(OrderConstants.policy_config + update.getPolicyId());
        return R.ok();
    }

    /**
     * 设置名称
     *
     * @param policy 策略
     */
    public void setValidName(PayPolicy policy) {
        try {
            //解析配置
            JSONArray polices = JSONArray.parseArray(policy.getConfig());

            boolean flag = false;
            for (int i = 0; i < polices.size(); i++) {
                JSONObject obj = polices.getJSONObject(i);
                if (StringUtils.isEmpty(obj.getString("fieldName"))) {
                    flag = true;
                    break;
                }
            }

            if (flag) {
                //获取校验字段名称
                List<SysDictDataVo> dicts = dictTypeService.selectDictDataByType("policy_fields");
                //根据dictValue 转换成Map
                Map<String, String> dictMap = dicts.stream().collect(Collectors.toMap(SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel));

                JSONArray newArray = new JSONArray();
                for (int i = 0; i < polices.size(); i++) {
                    JSONObject obj = polices.getJSONObject(i);
                    obj.put("fieldName", dictMap.get(obj.getString("validField")));
                    newArray.add(obj);
                }
                policy.setConfig(newArray.toJSONString());
            }
        } catch (Exception ignore) {
        }
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PayPolicy entity) {
        if (entity.getCountryType() == null) {
            entity.setCountryCode("");
        }
        if (Objects.equals(entity.getCountryType(), 1) ||Objects.equals(entity.getCountryType(), 2)) {
            if (StringUtils.isEmpty(entity.getCountryCode())) {
                throw new RuntimeException("国家简码不能为空");
            }
        }
    }

    /**
     * 校验并批量删除风控策略信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        for(Long id : ids){
            RedisUtils.deleteObject(OrderConstants.policy_config + id);
        }
        return baseMapper.deleteByIds(ids) > 0;
    }
}
